//
//  EskBarPlot.m
//  CorePlotSample
//
//  Created by Ken Wong on 8/7/11.
//  Copyright 2011 Essence Work LLC. All rights reserved.
//

/*
Status: changed
 Last Merge Date: 05-30-2012
Last Change Date: 
Changes:
 1. add x-axis label 
 2. bar color and remove outline
 2. redesign the animation on current amount on and off
*/


#import "EskBarPlot.h"
//#import "AgingModel.h"
#import "BalanceModel.h"


#define kDefaultPlot @"default"
//#define kSelectedPlot @"selected"
#define kRepeat 10 //repeat count, used for animation
#define kFrameRate 5  // frames per second, used for animation

@implementation EskBarPlot

//@synthesize agingData = _agingData;
@synthesize agingLabels = _agingLabels;
@synthesize delegate;
@synthesize dailyBalances = _dailyBalances;
@synthesize dailyKeys = _dailyKeys;

- (id)init
{
    self = [super init];
    if (self) 
    {
        
        BalanceModel *balance = [[BalanceModel alloc] init];
               
        _dailyBalances = balance.dailyBalances;
        _dailyKeys = [_dailyBalances allKeys];
        NSArray *sortedDailyKeys = [_dailyKeys sortedArrayUsingSelector:@selector(compare:)];
        _dailyKeys = sortedDailyKeys;
        numberOfPeriods = [_dailyKeys count];
        
        //the init date is the mid point of the entire range
        //NSString *initDateString = [_dailyKeys objectAtIndex:(numberOfPeriods/2)];
        NSString *initDateString = [_dailyKeys objectAtIndex:(numberOfPeriods-1)];
        //NSLog(@"initDateString = %@, numberOfPeriods=%i, 1st date=%@", initDateString,numberOfPeriods,[_dailyKeys objectAtIndex:0]);
        selectedDailyBalance = [_dailyBalances objectForKey:initDateString];
        asOfDateString = [NSString stringWithFormat:@"%@/%@/%@", [initDateString substringWithRange:NSMakeRange(4,2)],[initDateString substringWithRange:NSMakeRange(6,2)], [initDateString substringWithRange:NSMakeRange(0,4)]];
        
        
        //to animate curreny balance switch
        startingUndueAmount = [selectedDailyBalance.undueAmount intValue];  
        //NSLog(@"startingUndueAmount = %i", startingUndueAmount);
            
        // Initialize the currency formatter to support negative with the default currency style.
        currencyFormatter = [[NSNumberFormatter alloc] init];
        [currencyFormatter setNumberStyle:NSNumberFormatterCurrencyStyle];
        [currencyFormatter setNegativePrefix:@"-"];
        [currencyFormatter setNegativeSuffix:@""];
        
        agingLabelsWithCurrentAmount = balance.agingBucketLabels;
        agingLabelsNoCurrentAmount = balance.agingBucketLabelsNoCurrentAmount;
        
        
        displayCurrentBalance = YES;
        _agingLabels = agingLabelsWithCurrentAmount;
        

    }
    
    return self;
}

- (void)renderInLayer:(CPTGraphHostingView *)layerHostingView withTheme:(CPTTheme *)theme
{
    CGRect bounds = layerHostingView.bounds;
    
    // create and assign chart to the hosting view.
    graph = [[CPTXYGraph alloc] initWithFrame:bounds];
    layerHostingView.hostedGraph = graph;
    layerHostingView.backgroundColor = [UIColor colorWithWhite:0.7f alpha:1.0f]; 
    
    CPTGradient *plotAreaGradient = [CPTGradient gradientWithBeginningColor:[CPTColor colorWithGenericGray:0.9f]endingColor:[CPTColor colorWithGenericGray:0.6f]];
    plotAreaGradient.angle = -90.0;
    graph.plotAreaFrame.plotArea.fill = [CPTFill fillWithGradient:plotAreaGradient]; 
    
    [graph applyTheme:theme];
    graph.plotAreaFrame.masksToBorder = NO;
   
    graph.paddingLeft = 90.0;
	graph.paddingTop = 40.0;  //50.0
	graph.paddingRight = 50.0;
	graph.paddingBottom = 50.0;
    
    CPTMutableTextStyle *blackTextStyle = [[CPTMutableTextStyle alloc] init];
	//blackTextStyle.color = [CPTColor blackColor];
    blackTextStyle.color = [CPTColor colorWithComponentRed:0.2 green:0.2 blue:0.2 alpha:0.82]; //RGB:R51-G51-B51
	blackTextStyle.fontSize = 20.0;
    graph.titleTextStyle = blackTextStyle;
    graph.titleDisplacement = CGPointMake(0.0, 20.0); 
    graph.title = [NSString stringWithFormat:@"%@%@", @"Aging Bucket As Of ",asOfDateString];

    
    
    // chang the chart layer orders so the axis line is on top of the bar in the chart.
    NSArray *chartLayers = [[NSArray alloc] initWithObjects:[NSNumber numberWithInt:CPTGraphLayerTypeAxisLines],  
                                                            [NSNumber numberWithInt:CPTGraphLayerTypePlots], 
                                                            [NSNumber numberWithInt:CPTGraphLayerTypeMajorGridLines], 
                                                            [NSNumber numberWithInt:CPTGraphLayerTypeMinorGridLines],
                                                            [NSNumber numberWithInt:CPTGraphLayerTypeAxisLabels], 
                                                            [NSNumber numberWithInt:CPTGraphLayerTypeAxisTitles], nil];
    
    graph.topDownLayerOrder = chartLayers;
    
	// Add plot space for horizontal bar charts
    CPTXYPlotSpace *plotSpace = (CPTXYPlotSpace *)graph.defaultPlotSpace;    
    plotSpace.yRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromInt(0) length:CPTDecimalFromInt(50000)];
    plotSpace.xRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromInt(0) length:CPTDecimalFromInt(6)];
    
    // Setting X-Axis
    CPTXYAxisSet *axisSet = (CPTXYAxisSet *)graph.axisSet;
    CPTXYAxis *x = axisSet.xAxis;
    x.labelingPolicy = CPTAxisLabelingPolicyNone;
    //x.title = @"Country";
    x.titleOffset = 30.0f;
    x.majorTickLineStyle = nil;
    x.minorTickLineStyle = nil;
    x.majorIntervalLength = CPTDecimalFromString(@"1");
    x.orthogonalCoordinateDecimal = CPTDecimalFromString(@"0");
    x.labelExclusionRanges = [NSArray arrayWithObjects:[CPTPlotRange plotRangeWithLocation:CPTDecimalFromInt(6) length:CPTDecimalFromInt(1)], nil];
    
    // Use custom x-axis label so it will display product A, B, C... instead of 1, 2, 3, 4
    NSMutableArray *labels = [[NSMutableArray alloc] initWithCapacity:[_agingLabels count]];
    int idx = 0;
    for (NSString *product in _agingLabels)
    {
        CPTAxisLabel *label = [[CPTAxisLabel alloc] initWithText:product textStyle:x.labelTextStyle];
        label.tickLocation = CPTDecimalFromInt(idx);
        label.offset = 15.0f;
        [labels addObject:label];
        idx++;
    }
    x.axisLabels = [NSSet setWithArray:labels];
    
    // Setting up y-axis
	CPTXYAxis *y = axisSet.yAxis;
    y.majorIntervalLength = CPTDecimalFromInt(10000);
    //y.minorTicksPerInterval = 4;
    y.minorGridLineStyle = nil;
    y.title = @"Amount Overdue";
    y.labelExclusionRanges = [NSArray arrayWithObjects:[CPTPlotRange plotRangeWithLocation:CPTDecimalFromInt(0) length:CPTDecimalFromInt(0)], nil];
    
    barPlot = [[CPTBarPlot alloc] init];
    barPlot.fill = [CPTFill fillWithColor:[CPTColor colorWithComponentRed:0.22f green:0.55f blue:
                                           0.71f alpha:0.4f]];
    
    //y-axis stays in fixed position
    axisSet.yAxis.axisConstraints = [CPTConstraints constraintWithLowerOffset:0];
    
    CPTMutableLineStyle *borderLineStyle = [CPTMutableLineStyle lineStyle];
	borderLineStyle.lineWidth = 2.f;
    //borderLineStyle.lineColor = [CPTColor colorWithComponentRed:0.22f green:0.55f blue:0.71f alpha:1.0f];
    borderLineStyle.lineColor = [CPTColor clearColor];

    
    barPlot.lineStyle = borderLineStyle;
    barPlot.barWidth = CPTDecimalFromString(@"0.6");
    //barPlot.barOffset = CPTDecimalFromString(@"-0.3");
    barPlot.baseValue = CPTDecimalFromString(@"0");
    
    barPlot.dataSource = self;
    barPlot.barCornerRadius = 2.0f;
    barPlot.identifier = kDefaultPlot;
    barPlot.delegate = self;
    
    [graph addPlot:barPlot toPlotSpace:plotSpace];
    
    
    
    
    //**************************
    //selectedLineIndex = 2;
    
    //selected Plot
    /*selectedPlot = [[CPTBarPlot alloc] init];
    selectedPlot.fill = [CPTFill fillWithColor:[[CPTColor orangeColor] colorWithAlphaComponent:0.35f]];
    
    CPTMutableLineStyle *selectedBorderLineStyle = [CPTMutableLineStyle lineStyle];
	selectedBorderLineStyle.lineWidth = 3.0f;
    selectedBorderLineStyle.lineColor = [CPTColor orangeColor];
    selectedBorderLineStyle.dashPattern = [NSArray arrayWithObjects:[NSNumber numberWithFloat:10.0f], [NSNumber numberWithFloat:8.0f], nil];
    
    selectedPlot.lineStyle = selectedBorderLineStyle;
    selectedPlot.barWidth = CPTDecimalFromString(@"0.6");
    selectedPlot.baseValue = CPTDecimalFromString(@"0");
    
    selectedPlot.dataSource = self;
    selectedPlot.barCornerRadius = 2.0f;
    selectedPlot.identifier = kSelectedPlot;
    selectedPlot.delegate = self;
    [graph addPlot:selectedPlot toPlotSpace:plotSpace];*/

}


/*
- (void)barPlot:(EskBarPlot *)plot respondToLinePlotSelectedAtRecordIndex:(NSUInteger)index
{
    selectedLineIndex = index;
    [graph reloadData];
    
}  */    


- (void)barPlot:(EskBarPlot *)plot respondToLinePlotSelectedAtDate:(NSString *)selectedDateString
{   
    
    oldDailyBalance = selectedDailyBalance; //to animate selectedDate change
    selectedDailyBalance = [_dailyBalances objectForKey:selectedDateString];
    newDailyBalance =  selectedDailyBalance; //to animate selectedDate change
    
    asOfDateString = [NSString stringWithFormat:@"%@/%@/%@", [selectedDateString substringWithRange:NSMakeRange(4,2)],[selectedDateString substringWithRange:NSMakeRange(6,2)], [selectedDateString substringWithRange:NSMakeRange(0,4)]];
    graph.title = [NSString stringWithFormat:@"%@%@", @"Aging Bucket As Of ",asOfDateString];
    
    // to animate current balance switch
    startingUndueAmount = [selectedDailyBalance.undueAmount intValue];      
       
    dataTimer = [NSTimer timerWithTimeInterval:0.05
                                        target:self
                                      selector:@selector(newData:)
                                      userInfo:nil
                                       repeats:YES];
	[[NSRunLoop mainRunLoop] addTimer:dataTimer forMode:NSDefaultRunLoopMode];
    
    
}

-(void)newData:(NSTimer *)theTimer
{
    
    int newUndueAmount = [newDailyBalance.undueAmount intValue];
    int newBucketOneAmount = [newDailyBalance.bucketOneAmount intValue];
    int newBucketTwoAmount = [newDailyBalance.bucketTwoAmount intValue];
    int newBucketThreeAmount = [newDailyBalance.bucketThreeAmount intValue];
    int newAboveNinetyDaysAmount = [newDailyBalance.aboveNinetyDaysAmount intValue];
    
    
    int oldUndueAmount = [oldDailyBalance.undueAmount intValue];
    int oldBucketOneAmount = [oldDailyBalance.bucketOneAmount intValue];
    int oldBucketTwoAmount = [oldDailyBalance.bucketTwoAmount intValue];
    int oldBucketThreeAmount = [oldDailyBalance.bucketThreeAmount intValue];
    int oldAboveNinetyDaysAmount =[oldDailyBalance.aboveNinetyDaysAmount intValue];
    
    int diffUndueAmount = newUndueAmount - oldUndueAmount;
    int diffBucketOneAmount = newBucketOneAmount - oldBucketOneAmount;
    int diffBucketTwoAmount = newBucketTwoAmount - oldBucketTwoAmount;
    int diffBucketThreeAmount = newBucketThreeAmount - oldBucketThreeAmount;
    int diffAboveNinetyDaysAmount = newAboveNinetyDaysAmount - oldAboveNinetyDaysAmount;
    
    float unitUndueAmount = diffUndueAmount / kRepeat;
    float unitBucketOneAmount = diffBucketOneAmount / kRepeat;
    float unitBucketTwoAmount = diffBucketTwoAmount / kRepeat;
    float unitBucketThreeAmount = diffBucketThreeAmount / kRepeat;
    float unitAboveNinetyDaysAmount = diffAboveNinetyDaysAmount / kRepeat;
    
    int intrimUndueAmount = oldUndueAmount + unitUndueAmount * (timerCount+1);
    int intrimBucketOneAmount = oldBucketOneAmount + unitBucketOneAmount * (timerCount+1);
    int intrimBucketTwoAmount = oldBucketTwoAmount + unitBucketTwoAmount * (timerCount+1);
    int intrimBucketThreeAmount = oldBucketThreeAmount + unitBucketThreeAmount * (timerCount+1);
    int intrimAboveNinetyDaysAmount = oldAboveNinetyDaysAmount + unitAboveNinetyDaysAmount * (timerCount+1);
    
    if (!displayCurrentBalance) intrimUndueAmount =0;
    
    Balance *intrimDailyBalance = [[Balance alloc] init];
    intrimDailyBalance.undueAmount = [NSNumber numberWithInt:intrimUndueAmount];
    intrimDailyBalance.bucketOneAmount = [NSNumber numberWithInt:intrimBucketOneAmount];
    intrimDailyBalance.bucketTwoAmount = [NSNumber numberWithInt:intrimBucketTwoAmount];
    intrimDailyBalance.bucketThreeAmount = [NSNumber numberWithInt:intrimBucketThreeAmount];
    intrimDailyBalance.aboveNinetyDaysAmount = [NSNumber numberWithInt:intrimAboveNinetyDaysAmount];
    
    selectedDailyBalance = intrimDailyBalance;
    [barPlot reloadDataInIndexRange:NSMakeRange(0,6)];
    
       
    timerCount++;
    if (timerCount >kRepeat) {
        [theTimer invalidate];
        timerCount = 0;
    }
    
}



- (void)barPlot:(EskBarPlot *)plot respondToCurrentBalanceSwitch:(BOOL)switchOn
{
    
   
    
    if(switchOn){
        
        displayCurrentBalance = YES;
        dataTimer = [NSTimer timerWithTimeInterval:0.02
                                            target:self
                                          selector:@selector(barScrollIn:)
                                          userInfo:nil
                                           repeats:YES];
        [[NSRunLoop mainRunLoop] addTimer:dataTimer forMode:NSDefaultRunLoopMode];
        
        
    }
    else{
        displayCurrentBalance = NO;

        dataTimer = [NSTimer timerWithTimeInterval:0.02
                                            target:self
                                          selector:@selector(barScrollOff:)
                                          userInfo:nil
                                           repeats:YES];
        [[NSRunLoop mainRunLoop] addTimer:dataTimer forMode:NSDefaultRunLoopMode];

        
    }

      [self performSelector:@selector(rescaleTheBarPlot) withObject:nil afterDelay:0.4];
       
    
    
    
  
    /*CABasicAnimation *scaling =[CABasicAnimation animationWithKeyPath:@"transform.translation.x"];
    
    if(switchOn){
        scaling.fromValue = [NSNumber numberWithFloat:-45.0];
        scaling.toValue = [NSNumber numberWithFloat:0.0];
        displayCurrentBalance = YES;
        [barPlot reloadDataInIndexRange:NSMakeRange(0,6)]; //bar appears before rolling in
    }else{
        scaling.fromValue = [NSNumber numberWithFloat:0.0];
        scaling.toValue = [NSNumber numberWithFloat:-60.0];
        displayCurrentBalance = NO;
    }
        
    scaling.duration = 1.0f; // Duration
    scaling.removedOnCompletion = NO;
    scaling.fillMode = kCAFillModeForwards;
    [barPlot addAnimation:scaling forKey:@"scaling"]; 
    
    [self performSelector:@selector(rescaleTheBarPlot) withObject:nil afterDelay:1.0];
     */
    
      
}

-(void)barScrollIn:(NSTimer *)theTimer{
    
    CPTXYPlotSpace *plotSpace = (CPTXYPlotSpace *)graph.defaultPlotSpace;   
    plotSpace.xRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromFloat(1.5-timerCount*0.1) length:CPTDecimalFromInt(6)];
    
    [barPlot reloadData];

    
    timerCount++;
    if (timerCount >15) {
        [theTimer invalidate];
        timerCount = 0;
    }

    
}

-(void)barScrollOff:(NSTimer *)theTimer{
    
    CPTXYPlotSpace *plotSpace = (CPTXYPlotSpace *)graph.defaultPlotSpace;   
    plotSpace.xRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromFloat(timerCount*0.1) length:CPTDecimalFromInt(6)];
    
    [barPlot reloadData];
    
    
    timerCount++;
    if (timerCount >15) {
        [theTimer invalidate];
        timerCount = 0;
    }

    
}


- (void)rescaleTheBarPlot{
    
    CPTXYPlotSpace *plotSpace = (CPTXYPlotSpace *)graph.defaultPlotSpace;    
    CPTXYAxisSet *axisSet = (CPTXYAxisSet *)graph.axisSet;
    //CPTXYAxis *x = axisSet.xAxis;
    CPTXYAxis *y = axisSet.yAxis;
    tempIncreaseValue = NO;
    tempReduceValue = NO;

    
    if (displayCurrentBalance) {
        
        _agingLabels = agingLabelsWithCurrentAmount;
                
        //plotSpace.xRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromInt(0) length:CPTDecimalFromInt(6)];
        
        plotSpace.yRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromInt(0) length:CPTDecimalFromInt(50000)];
        y.majorIntervalLength = CPTDecimalFromInt(10000);
        
        //this flag is to avoid the bars redrawn due to rescaling
        tempIncreaseValue = YES;
        //[barPlot reloadDataInIndexRange:NSMakeRange(0,6)];
        [barPlot reloadData];
        tempIncreaseValue = NO;
        
        switchDailyBalance = selectedDailyBalance;
        dataTimer = [NSTimer timerWithTimeInterval:0.05
                                            target:self
                                          selector:@selector(currentBalanceData:)
                                          userInfo:nil
                                           repeats:YES];
        [[NSRunLoop mainRunLoop] addTimer:dataTimer forMode:NSDefaultRunLoopMode];

        
    } else{
        
        _agingLabels = agingLabelsNoCurrentAmount;
                
        //plotSpace.xRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromInt(0) length:CPTDecimalFromInt(6)];
        
        plotSpace.yRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromInt(0) length:CPTDecimalFromInt(15000)];
        
        y.majorIntervalLength = CPTDecimalFromInt(3000);
        
         //this flag is to avoid the bars redrawn due to rescaling
        tempReduceValue = YES;
        [barPlot reloadData];
        //[barPlot reloadDataInIndexRange:NSMakeRange(1,6)];
        tempReduceValue = NO;
               
        switchDailyBalance = selectedDailyBalance;
        dataTimer = [NSTimer timerWithTimeInterval:0.05
                                            target:self
                                          selector:@selector(noCurrentBalanceData:)
                                          userInfo:nil
                                           repeats:YES];
        [[NSRunLoop mainRunLoop] addTimer:dataTimer forMode:NSDefaultRunLoopMode];
        
    }
    
    
   /* 
    NSMutableArray *labels = [[NSMutableArray alloc] initWithCapacity:[_agingLabels count]];
    int idx = 0;
    for (NSString *product in _agingLabels)
    {
        CPTAxisLabel *label =[[CPTAxisLabel alloc] initWithText:product textStyle:x.labelTextStyle];
        label.offset = 5.0f;
        
        if(displayCurrentBalance)
            label.tickLocation = CPTDecimalFromInt(idx);
        else
            label.tickLocation = [[NSNumber numberWithFloat:(idx+0.35f)] decimalValue];
        
        [labels addObject:label];
        idx++;
    }
    x.axisLabels = [NSSet setWithArray:labels];
       */
}


-(void)noCurrentBalanceData:(NSTimer *)theTimer
{
   
    int undueAmount = [switchDailyBalance.undueAmount intValue];
    int bucketOneAmount = [switchDailyBalance.bucketOneAmount intValue];
    int bucketTwoAmount = [switchDailyBalance.bucketTwoAmount intValue];
    int bucketThreeAmount = [switchDailyBalance.bucketThreeAmount intValue];
    int aboveNinetyDaysAmount = [switchDailyBalance.aboveNinetyDaysAmount intValue];
    
    float unitUndueAmount = (undueAmount*0.7) / kRepeat;
    float unitBucketOneAmount = (bucketOneAmount*0.7) / kRepeat;
    float unitBucketTwoAmount = (bucketTwoAmount*0.7) / kRepeat;
    float unitBucketThreeAmount = (bucketThreeAmount*0.7) / kRepeat;
    float unitAboveNinetyDaysAmount = (aboveNinetyDaysAmount*0.7) / kRepeat;
    
    //The max of y-axis when current amount off is 15000, which is 0.3 of 50000, the max value when the current amount is on.
    float intrimUndueAmount = (undueAmount*0.3) + (unitUndueAmount * timerCount);
    float intrimBucketOneAmount = (bucketOneAmount*0.3) + (unitBucketOneAmount * timerCount);
    float intrimBucketTwoAmount = (bucketTwoAmount*0.3) + (unitBucketTwoAmount * timerCount);
    float intrimBucketThreeAmount = (bucketThreeAmount*0.3) + (unitBucketThreeAmount * timerCount);
    float intrimAboveNinetyDaysAmount = (aboveNinetyDaysAmount*0.3) + (unitAboveNinetyDaysAmount * timerCount);
    
    //NSLog(@"timerCount=%i,bucketOneAmount=%i,unitBucketOneAmount=%f,intrimBucketOneAmount=%f",timerCount,bucketOneAmount,unitBucketOneAmount,intrimBucketOneAmount);
    
    //if (!displayCurrentBalance) intrimUndueAmount =0;
    
    Balance *intrimDailyBalance = [[Balance alloc] init];
    intrimDailyBalance.undueAmount = [NSNumber numberWithFloat:intrimUndueAmount];
    intrimDailyBalance.bucketOneAmount = [NSNumber numberWithFloat:intrimBucketOneAmount];
    intrimDailyBalance.bucketTwoAmount = [NSNumber numberWithFloat:intrimBucketTwoAmount];
    intrimDailyBalance.bucketThreeAmount = [NSNumber numberWithFloat:intrimBucketThreeAmount];
    intrimDailyBalance.aboveNinetyDaysAmount = [NSNumber numberWithFloat:intrimAboveNinetyDaysAmount];
    
    selectedDailyBalance = intrimDailyBalance;
    [barPlot reloadDataInIndexRange:NSMakeRange(0,6)];
        
    timerCount++;
    if (timerCount >kRepeat) {
        [theTimer invalidate];
        timerCount = 0;
    }
}


-(void)currentBalanceData:(NSTimer *)theTimer
{
    
    int undueAmount = [switchDailyBalance.undueAmount intValue];
    int bucketOneAmount = [switchDailyBalance.bucketOneAmount intValue];
    int bucketTwoAmount = [switchDailyBalance.bucketTwoAmount intValue];
    int bucketThreeAmount = [switchDailyBalance.bucketThreeAmount intValue];
    int aboveNinetyDaysAmount = [switchDailyBalance.aboveNinetyDaysAmount intValue];
    
    
    //The max of y-axis when current amount off is 15000, which is 0.3 of 50000, the max value when the current amount is on.
    //However, undueAmount is an exception. Scale of 0.3 will cause huge intrimAmount, like 9382 while other bars like 1446. Therefore, the animation looks the current amount not changed and suddenly droppped sharply. Changing the scale helps this issue.
    float unitUndueAmount = ((undueAmount/0.8)-undueAmount) / kRepeat;
    float unitBucketOneAmount = ((bucketOneAmount/0.3)-bucketOneAmount) / kRepeat;
    float unitBucketTwoAmount = ((bucketTwoAmount/0.3)-bucketTwoAmount) / kRepeat;
    float unitBucketThreeAmount = ((bucketThreeAmount/0.3)-bucketThreeAmount) / kRepeat;
    float unitAboveNinetyDaysAmount = ((aboveNinetyDaysAmount/0.3)-aboveNinetyDaysAmount) / kRepeat;
   
    float intrimUndueAmount = (undueAmount/0.8) - (unitUndueAmount * timerCount);
    float intrimBucketOneAmount = (bucketOneAmount/0.3) - (unitBucketOneAmount * timerCount);
    float intrimBucketTwoAmount = (bucketTwoAmount/0.3) - (unitBucketTwoAmount * timerCount);
    float intrimBucketThreeAmount = (bucketThreeAmount/0.3) - (unitBucketThreeAmount * timerCount);
    float intrimAboveNinetyDaysAmount = (aboveNinetyDaysAmount/0.3) - (unitAboveNinetyDaysAmount * timerCount);
    
    //NSLog(@"timerCount=%i,undueAmount=%i,unitUndueAmount=%f,intrimUndueAmount=%f",timerCount,undueAmount,unitUndueAmount,intrimUndueAmount);
    //NSLog(@"timerCount=%i,bucketOneAmount=%i,unitBucketOneAmount=%f,intrimBucketOneAmount=%f",timerCount,bucketOneAmount,unitBucketOneAmount,intrimBucketOneAmount);
    
    
    //if (!displayCurrentBalance) intrimUndueAmount =0;
    
    Balance *intrimDailyBalance = [[Balance alloc] init];
    intrimDailyBalance.undueAmount = [NSNumber numberWithFloat:intrimUndueAmount];
    intrimDailyBalance.bucketOneAmount = [NSNumber numberWithFloat:intrimBucketOneAmount];
    intrimDailyBalance.bucketTwoAmount = [NSNumber numberWithFloat:intrimBucketTwoAmount];
    intrimDailyBalance.bucketThreeAmount = [NSNumber numberWithFloat:intrimBucketThreeAmount];
    intrimDailyBalance.aboveNinetyDaysAmount = [NSNumber numberWithFloat:intrimAboveNinetyDaysAmount];
    
    selectedDailyBalance = intrimDailyBalance;
    [barPlot reloadDataInIndexRange:NSMakeRange(0,6)];
    
    /*if (displayCurrentBalance){
     [barPlot reloadDataInIndexRange:NSMakeRange(0,6)];
     } else {
     [barPlot reloadDataInIndexRange:NSMakeRange(0,5)];
     };*/
    
    timerCount++;
    if (timerCount >kRepeat) {
        [theTimer invalidate];
        timerCount = 0;
    }
}

// We can decide what color to fill the bar in the chart at the given index here.
// In this case, when the given index match the selected bar index, we change the color
// to clear color, so we select Plot layer on top of the default one can has it own transparent color.
-(CPTFill *)barFillForBarPlot:(CPTBarPlot *)barPlot recordIndex:(NSUInteger)index
{  
    
    CPTColor *greenColor  = [CPTColor colorWithComponentRed:0.078 green:0.529 blue:0.0 alpha:1.0]; //RGB: 20-135-0  (green)
    CPTColor *greenEndColor  = [CPTColor colorWithComponentRed:0.216 green:0.671 blue:0.004 alpha:1.0]; //RGB: 55-171-1  (green)
    
    CPTColor *blueColor = [CPTColor colorWithComponentRed:0.051 green:0.388 blue:0.894 alpha:1.0];
    //RGB: 130-99-228  (blue)
    CPTColor *blueEndColor = [CPTColor colorWithComponentRed:0.129 green:0.545 blue:0.894 alpha:1.0];//RGB: 33-139-228  (blue)
    
    CPTColor *orangeColor = [CPTColor colorWithComponentRed:0.882 green:0.251 blue:0.141 alpha:1.0];   //RGB: 225-64-36  (orange)
    CPTColor *orangeEndColor = [CPTColor colorWithComponentRed:0.922 green:0.361 blue:0.125 alpha:1.0]; //RGB: 235-92-32  (orange)
    
    CPTGradient *blueGradient = [CPTGradient gradientWithBeginningColor:blueColor endingColor: blueEndColor];
    blueGradient.angle = -90.0;
     
    CPTGradient *greenGradient = [CPTGradient gradientWithBeginningColor: greenColor endingColor: greenEndColor];
    greenGradient.angle = -90.0;
      
    CPTGradient *orangeGradient = [CPTGradient gradientWithBeginningColor: orangeColor endingColor: orangeEndColor];
    orangeGradient.angle = -90.0;
    
    CPTFill *fillColor;
    
    if (index == 1){
       fillColor = [CPTFill fillWithGradient:greenGradient];
    } else if (index == 5)
    {
        fillColor = [CPTFill fillWithGradient:orangeGradient];
    } else
    {
       fillColor = [CPTFill fillWithGradient:blueGradient];
    };

    
    return fillColor;
}


#pragma mark - CPTBarPlot Delegates
- (void)barPlot:(CPTBarPlot *)plot barWasSelectedAtRecordIndex:(NSUInteger)index 
{   
    [barPlot reloadData];
    selectedBarIndex = index;
    
    //NSLog(@"bar index selected = %d", index);

    
    // Notify the view controller that a bar was selected, so it can change the label description.
    if ([delegate respondsToSelector:@selector(barPlot:barWasSelectedAtRecordIndex:currentBalanceDisplayed:)])
    {
        [delegate barPlot:self barWasSelectedAtRecordIndex:index currentBalanceDisplayed: displayCurrentBalance];
        //NSLog(@"respond to bar selection"); 
        
    }
}

// This method is call to put the number figure on the top tip of the bar.
/*-(CPTLayer *)dataLabelForPlot:(CPTPlot *)plot recordIndex:(NSUInteger)index 
{   //NSLog(@"index2 = %d", index);
    if (index == selectedBarIndex && [plot.identifier isEqual:kSelectedPlot]) 
    {
        CPTTextLayer *selectedText = [CPTTextLayer layer];
        //????selectedText.text = [currencyFormatter stringFromNumber:[_agingData objectAtIndex:index]];
        CPTMutableTextStyle *labelTextStyle = [CPTMutableTextStyle textStyle];
        labelTextStyle.fontSize = 16;
        labelTextStyle.color = [CPTColor purpleColor];
        selectedText.textStyle = labelTextStyle;
        return selectedText;
    }
    return nil;
}
*/

#pragma mark - CPTPlotDataSource Delegates
- (NSUInteger)numberOfRecordsForPlot:(CPTPlot *)plot
{
    //if (displayCurrentBalance)
        return 6;
   // else
        //return 5;
    
}

- (NSNumber *)numberForPlot:(CPTPlot *)plot field:(NSUInteger)fieldEnum recordIndex:(NSUInteger)index
{
    //NSLog(@"bar index = %d", index);
    if (index == 0)
        return nil;
    
    NSNumber *num = nil;
    if (fieldEnum == CPTBarPlotFieldBarLocation)
    {
        num = [NSNumber numberWithInt:index];
        
    }
    else if (fieldEnum == CPTBarPlotFieldBarTip)
    {
        // The select plot will only return a value when a bar was selected.
        if (plot.identifier == kDefaultPlot) 
            //|| (plot.identifier == kSelectedPlot && index == selectedBarIndex))
        {
            //NSLog(@"selectedLineIndex=%i",selectedLineIndex );
            
           
            if (selectedDailyBalance)
            {
                switch (index) {
                    case 0:
                        num = [NSNumber numberWithInt:0];
                        break;
                    case 1:
                        if (displayCurrentBalance){
                            //this flag prevents bars sudden growth due to rescaling
                            if (tempIncreaseValue){
                                int tempUndueAmt = [selectedDailyBalance.undueAmount intValue];
                                num = [NSNumber numberWithInt:(tempUndueAmt/0.8)];
                                
                            }
                            else 
                                num = selectedDailyBalance.undueAmount;
                               
                        } else{
                            if (tempReduceValue){
                                int tempUndueAmt = [selectedDailyBalance.undueAmount intValue];
                                num = [NSNumber numberWithInt:(tempUndueAmt*0.3)];
                                 
                            }
                            else 
                                num = selectedDailyBalance.undueAmount;
                                //num = [NSNumber numberWithInt:0];
                        }
                                                   
                        break;
                        

                    case 2:
                        if (displayCurrentBalance){
                            if (tempIncreaseValue){
                                int tempOneAmt = [selectedDailyBalance.bucketOneAmount intValue];
                                num = [NSNumber numberWithInt:(tempOneAmt/0.3)];
                            }
                            else
                                num = selectedDailyBalance.bucketOneAmount;
                        }else{
                            if (tempReduceValue){
                                int tempOneAmt = [selectedDailyBalance.bucketOneAmount intValue];
                                num = [NSNumber numberWithInt:(tempOneAmt*0.3)];
                            }
                            else 
                                num = selectedDailyBalance.bucketOneAmount;
                        }

                        break;
                    case 3:
                        if (displayCurrentBalance){
                            if (tempIncreaseValue){
                                int tempTwoAmt = [selectedDailyBalance.bucketTwoAmount intValue];
                                num = [NSNumber numberWithInt:(tempTwoAmt/0.3)];
                            }
                            else
                                num = selectedDailyBalance.bucketTwoAmount;
                        }else{
                            if (tempReduceValue){
                                int tempTwoAmt = [selectedDailyBalance.bucketTwoAmount intValue];
                                num = [NSNumber numberWithInt:(tempTwoAmt*0.3)];
                            }
                            else 
                                num = selectedDailyBalance.bucketTwoAmount;
                        }
                        
                        break;  
                    case 4:
                        if (displayCurrentBalance){
                            if (tempIncreaseValue){
                                int tempThreeAmt = [selectedDailyBalance.bucketThreeAmount intValue];
                                num = [NSNumber numberWithInt:(tempThreeAmt/0.3)];
                            }
                            else
                                num = selectedDailyBalance.bucketThreeAmount;
                        }else{
                            if (tempReduceValue){
                                int tempThreeAmt = [selectedDailyBalance.bucketThreeAmount intValue];
                                num = [NSNumber numberWithInt:(tempThreeAmt*0.3)];
                            }
                            else 
                                num = selectedDailyBalance.bucketThreeAmount;
                        }

                        
                        break; 
                    case 5:
                        if (displayCurrentBalance){
                            if (tempIncreaseValue){
                                int tempAboveAmt = [selectedDailyBalance.aboveNinetyDaysAmount intValue];
                                num = [NSNumber numberWithInt:(tempAboveAmt/0.3)];
                            }
                            else
                                num = selectedDailyBalance.aboveNinetyDaysAmount;
                        }else{
                            if (tempReduceValue){
                                int tempAboveAmt = [selectedDailyBalance.aboveNinetyDaysAmount intValue];
                                num = [NSNumber numberWithInt:(tempAboveAmt*0.3)];
                            }
                            else 
                                num = selectedDailyBalance.aboveNinetyDaysAmount;
                        }

                        
                        break;
                    default:
                        num = [NSNumber numberWithInt:0];
                        break;
                }

            }
                  }

    }
    //NSLog(@"index =%d, num=%@,fieldEnum=%d", index, num, fieldEnum);
    return num;
}



@end
